package com.hehe.conversion.hehemiddleware.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.hehe.conversion.hehemiddleware.common.ApiResponse;
import com.hehe.conversion.hehemiddleware.common.InvoiceType;
import com.hehe.conversion.hehemiddleware.model.req.ImageUploadRequest;
import com.hehe.conversion.hehemiddleware.model.resp.bill.*;
import com.hehe.conversion.hehemiddleware.model.resp.hehe.Item;
import com.hehe.conversion.hehemiddleware.model.resp.hehe.ObjectList;
import com.hehe.conversion.hehemiddleware.model.resp.hehe.Page;
import com.hehe.conversion.hehemiddleware.model.resp.hehe.ResponseRoot;
import com.hehe.conversion.hehemiddleware.model.resp.hehe.Result;
import com.hehe.conversion.hehemiddleware.model.resp.ruizhen.IdentifyResult;
import com.hehe.conversion.hehemiddleware.model.resp.ruizhen.Response;
import com.hehe.conversion.hehemiddleware.model.resp.ruizhen.RzData;
import com.hehe.conversion.hehemiddleware.service.InvoiceProcessingService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;


@Service
@Slf4j
public class InvoiceProcessingServiceImpl implements InvoiceProcessingService {
    @Value("${hehe.billidentification.url}")
    String billidentificationUrl;

    @Autowired
    RestTemplate restTemplate;
    @Value("${hehe.appKey}")
    String appkey;

    @Value("${hehe.appSecret}")
    String appSecret;

    @Value("${hehe.secret.header.name:App_secret}")
    String secretHeaderName;

    @Value("${hehe.appkey.header.name:App_key}")
    String appKeyHeaderName;

    @Override
    public ApiResponse handleRequest(ImageUploadRequest imageUploadRequest) {
        log.info("InvoiceProcessingServiceImpl handleRequest request app_key:{},token:{}",imageUploadRequest.getApp_key(),imageUploadRequest.getToken());
        try{
            //1.构建请求文件
            byte[] processImageUploadRequest = processImageUploadRequest(imageUploadRequest);
            //2.发送合合请求
            // 设置请求头
            log.info("InvoiceProcessingServiceImpl sendRequest billidentificationUrl:{},appkey:{},appSecret:{},appKeyHeaderName:{},secretHeaderName:{}",billidentificationUrl,appkey,appSecret,appKeyHeaderName,secretHeaderName);
            HttpRequest request = HttpRequest.post(billidentificationUrl)
//                    .header("x-ti-app-id", appkey)
//                    .header("x-ti-secret-code", appSecret)
                    .header(appKeyHeaderName, appkey)
                    .header(secretHeaderName, appSecret)
                    .contentType("application/octet-stream");
            // 发送PDF文件的二进制流
            request.body(processImageUploadRequest);
            // 发送请求并接收响应
            HttpResponse response = request.execute();
            log.info("InvoiceProcessingServiceImpl response status:{},result:{}",response.getStatus(),response.body());
            if (response.isOk()) {
                //3.返回数据解析转换
                ResponseRoot responseRoot = JSONObject.parseObject(response.body(), ResponseRoot.class);
                if(responseRoot!=null&&responseRoot.getCode()==200){
                    //4.输出.
                    return conversionResponse(responseRoot,generateImageHash(processImageUploadRequest));
                }
            }
            log.error("request fail.");
        }catch (Exception e){
            log.error("InvoiceProcessingServiceImpl handleRequest error",e);
        }
        return new ApiResponse(0,null,"操作失败",10002);
    }

    public static String getDate(String dateTimeStr) {
        try{
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");

            LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, formatter);

            return dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        }catch (Exception e){
            log.error("获取时间失败",e);
        }
        return null;
    }
    public static String getTime(String dateTimeStr) {
        try {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, formatter);
        return dateTime.format(DateTimeFormatter.ofPattern("HH:mm"));
        }catch (Exception e){
            log.error("获取时间失败",e);
        }
        return null;
    }
    public static String getCnDateTime(String dateTimeStr) {
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, formatter);
            return dateTime.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
        }catch (Exception e){
            log.error("获取时间失败",e);
        }
        return null;
    }
    public static String generateImageHash(byte[] imageData) {
        try {
            // 创建一个MessageDigest实例，指定使用SHA-1算法
            MessageDigest digest = MessageDigest.getInstance("SHA-1");

            // 对图片数据进行哈希计算
            byte[] hashBytes = digest.digest(imageData);

            // 将哈希值转换为十六进制字符串
            StringBuilder hexString = new StringBuilder();
            for (int i = 0; i < hashBytes.length; i++) {
                String hex = Integer.toHexString(0xff & hashBytes[i]);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }

            // 返回哈希字符串
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            // 处理异常：NoSuchAlgorithmException
            log.error("generateImageHash",e);
            return null;
        }
    }
    /**
     * 将合合返回的接口数据进行整合成睿真的输出数据
     * @param responseRoot
     * @return
     */
    private ApiResponse conversionResponse(ResponseRoot responseRoot,String imgSha){
        log.info("InvoiceProcessingServiceImpl conversionResponse 进入数据转换.");
        if(CollectionUtil.isEmpty(responseRoot.getPages())){
            return new ApiResponse(1,null,"未获取到数据",10002);
        }
        Response response=new Response();
        RzData data=new RzData();
        data.setMessage("success");
        data.setTimestamp(System.currentTimeMillis());
        data.setResult(1);
        data.setVersion("1.5.8");
        List<IdentifyResult> identify_results=new ArrayList<>();
        List<Page> pages = responseRoot.getPages();
        AtomicReference<Long> timeCost= new AtomicReference<>(0L);
        pages.forEach(item->{
            Result result = item.getResult();
            List<ObjectList> objectList = result.getObjectList();
            int costTime = item.getCostTime();
            timeCost.updateAndGet(v -> v + costTime);
            objectList.forEach(list->{
                InvoiceType invoiceType = InvoiceType.fromString(list.getType());
                if(invoiceType==null){
                    log.error("InvoiceProcessingServiceImpl conversionResponse 转换合合类型未匹配 type:{}",list.getType());
                    return;
                }
                IdentifyResult identifyResult=new IdentifyResult();
                identifyResult.setType(invoiceType.getCode()+"");
                identifyResult.setOrientation(list.getImageAngle());
                identifyResult.setPage(item.getPageNumber());
                List<Integer> image_size=new ArrayList<>();
                image_size.add(list.getRotatedImageWidth());
                image_size.add(list.getRotatedImageHeight());
                identifyResult.setImage_size(image_size);
                if(CollectionUtil.isNotEmpty(list.getPosition())){
                    //坐标位置
                    List<Integer> region=new ArrayList<>();
                    //取第一跟第三个
                    region.add(list.getPosition().get(0));
                    region.add(list.getPosition().get(1));
                    region.add(list.getPosition().get(4));
                    region.add(list.getPosition().get(5));
                    identifyResult.setRegion(region);
                }
                switch (invoiceType) {
                    //机动车销售统一发票
                    case MOTOR_VEHICLE_SALE_INVOICE:
                        createParamByMotorVehicle(list,identifyResult);
                        break;
                    //二手车销售统一发票
                    case USED_CAR_PURCHASE_INVOICE:
                        createParamByUsedCar(list,identifyResult);
                        break;
                    //卷票
                    case VAT_ROLL_INVOICE:
                        createParamByVatRollInvoice(list,identifyResult);
                        break;
                    //增值税普通发票
                    case VAT_COMMON_INVOICE:
                    case VAT_SPECIAL_INVOICE:
                    case VAT_ELECTRONIC_INVOICE:
                    case VAT_ELECTRONIC_TOLL_INVOICE:
                    case MACHINE_PRINTED_INVOICE:
                    case VAT_ELECTRONIC_SPECIAL_INVOICE:
                    case VAT_ELECTRONIC_INVOICE_NEW:
                    case VAT_ELECTRONIC_SPECIAL_INVOICE_NEW:
                    case BLOCKCHAIN_ELECTRONIC_INVOICE:
                        createParamByVatCommonInvoice(list,identifyResult);
                        break;
                    //定额发票
                    case QUOTA_INVOICE:
                        createParamByQuota(list,identifyResult);
                        break;
                    //火车票
                    case TRAIN_TICKET:
                        createParamByTrain(list,identifyResult);
                        break;
                    //出租车
                    case TAXI_TICKET:
                        createParamByTaxi(list,identifyResult);
                        break;
                    //过路费发票
                    case VEHICLE_TOLL:
                        createParamByVehicle(list,identifyResult);
                        break;
                    //客运汽车
                    case PASSENGER_TRANSPORT_INVOICE:
                        createParamByPassengerTranSport(list,identifyResult);
                        break;
                    //航空运输电子客票行程单
                    case AIR_TRANSPORT:
                        createParamByAir(list,identifyResult);
                        break;
                    //消费小票
                    case SHOP_RECEIPT:
                        createParamByShop(list,identifyResult);
                        break;
                    //机打发票
                    case GENERAL_MACHINE_INVOICE:
                        createParamByGeneral(list,identifyResult);
                        break;
                    //医疗票据
                    case MEDICAL_RECEIPT:
                        createParamByMedical(list,identifyResult);
                        break;
                    //非税收入类票据
                    case NON_TAX_INCOME_UNIFIED_BILL:
                        createParamByNonTaxIncomeBill(list,identifyResult);
                        break;
                    default:
                        log.error("InvoiceProcessingServiceImpl conversionResponse match fail.");
                        break;
                }
                identify_results.add(identifyResult);
            });
        });
        data.setTime_cost(timeCost.get().toString());
        data.setIdentify_results(identify_results);
        data.setSha1(imgSha);
        data.setId(UUID.fastUUID().toString().replaceAll("-",""));
        response.setData(data);
        log.info("InvoiceProcessingServiceImpl conversionResponse 进入数据转换结束.");
        return new ApiResponse(1,response);
    }

    /**
     * 二手车销售统一发票
     * @param list
     * @param identifyResult
     */
    private void createParamByUsedCar(ObjectList list, IdentifyResult identifyResult) {
        UsedCarDetails details=new UsedCarDetails(); // 发票识别的具体信息
        List<Item> itemList = list.getItemList();
        details.setKind(list.getKindDescription());
        details.setCode(getItemValByKey("vehicle_invoice_daima",itemList));
        details.setNumber(getItemValByKey("vehicle_invoice_haoma",itemList));
        details.setDate(getItemValByKey("vehicle_invoice_issue_date",itemList));
        details.setTotal(getItemValByKey("vehicle_invoice_total_price_digits",itemList));
        details.setSeller(getItemValByKey("vehicle_invoice_seller",itemList));
        details.setSellerId(getItemValByKey("vehicle_invoice_seller_id",itemList));
        details.setSellerAddress(getItemValByKey("vehicle_invoice_seller_addr",itemList));
        details.setBuyer(getItemValByKey("vehicle_invoice_buyer",itemList));
        details.setBuyerId(getItemValByKey("vehicle_invoice_buyer_id",itemList));
        details.setBuyerAddress(getItemValByKey("vehicle_invoice_buyer_addr",itemList));
        details.setCompanyName(getItemValByKey("vehicle_invoice_market",itemList));
        details.setCompanyTaxId(getItemValByKey("vehicle_invoice_market_tax_id",itemList));
        details.setCompanyBankAccount(getItemValByKey("vehicle_invoice_market_bank_acount",itemList));
        details.setCompanyPhone(getItemValByKey("vehicle_invoice_market_phone",itemList));
        details.setCompanyAddress(getItemValByKey("vehicle_invoice_market_addr",itemList));
        details.setLicensePlate(getItemValByKey("vehicle_invoice_plate_num",itemList));
        details.setRegistrationNumber(getItemValByKey("vehicle_invoice_register_num",itemList));
        details.setCarCode(getItemValByKey("vehicle_invoice_vin",itemList));
        details.setCarModel(getItemValByKey("vehicle_invoice_car_model",itemList));
        details.setMachineCode(getItemValByKey("vehicle_invoice_machine_id",itemList));
        details.setSellerTel(getItemValByKey("vehicle_invoice_seller_phone",itemList));
        details.setCarType(getItemValByKey("vehicle_invoice_vehicle_type",itemList));
        details.setBuyerTel(getItemValByKey("vehicle_invoice_buyer_phone",itemList));
        details.setAuctionBankAccount(getItemValByKey("vehicle_invoice_auction_house_bank_account",itemList));
        String exist_stample = getItemValByKey("exist_stample", itemList);
        if(StringUtils.isNotBlank(exist_stample)&&exist_stample.equals("True")){
            details.setCompanySeal("1");
        }else{
            details.setCompanySeal("0");
        }
        identifyResult.setDetails(details);
    }

    /**
     * 机动车销售统一发票
     * @param list
     * @param identifyResult
     */
    private void createParamByMotorVehicle(ObjectList list, IdentifyResult identifyResult) {
        MotorVehicleDetails details=new MotorVehicleDetails(); // 发票识别的具体信息
        List<Item> itemList = list.getItemList();
        details.setKind(list.getKindDescription());
        details.setCode(getItemValByKey("vehicle_invoice_daima",itemList));
        details.setNumber(getItemValByKey("vehicle_invoice_haoma",itemList));
        details.setMachineCode(getItemValByKey("vehicle_invoice_jida_daima",itemList));
        details.setMachineNumber(getItemValByKey("vehicle_invoice_jida_haoma",itemList));
        details.setDate(getItemValByKey("vehicle_invoice_issue_date",itemList));
        details.setPretaxAmount(getItemValByKey("vehicle_invoice_price_without_tax",itemList));
        details.setTotal(getItemValByKey("vehicle_invoice_total_price_digits",itemList));
        details.setSeller(getItemValByKey("vehicle_invoice_dealer",itemList));
        details.setSellerTaxId(getItemValByKey("vehicle_invoice_seller_tax_id",itemList));
        details.setAddress(getItemValByKey("vehicle_invoice_seller_address",itemList));
        details.setPhone(getItemValByKey("vehicle_invoice_telephone",itemList));
        details.setAccount(getItemValByKey("vehicle_invoice_seller_bank_account",itemList));
        details.setBuyer(getItemValByKey("vehicle_invoice_buyer",itemList));
        details.setBuyerId(getItemValByKey("vehicle_invoice_buyer_id",itemList));
        details.setTaxAuthorities(getItemValByKey("vehicle_invoice_tax_authorith",itemList));
        details.setTaxAuthoritiesCode(getItemValByKey("vehicle_invoice_tax_author_id",itemList));
        details.setCarCode(getItemValByKey("vehicle_invoice_car_vin",itemList));
        details.setCarEngineCode(getItemValByKey("vehicle_invoice_engine_id",itemList));
        details.setCarModel(getItemValByKey("vehicle_invoice_car_model",itemList));
        details.setCertificateNumber(getItemValByKey("vehicle_invoice_cert_id",itemList));
        details.setTax(getItemValByKey("vehicle_invoice_tax_amount",itemList));
        details.setTaxRate(getItemValByKey("vehicle_invoice_tax_rate",itemList));
        details.setCarType(getItemValByKey("vehicle_invoice_vehicle_type",itemList));
        details.setTonnage(getItemValByKey("vehicle_invoice_tonnage",itemList));
        details.setIssuer(getItemValByKey("vehicle_invoice_issued_by",itemList));
        details.setTaxNum(getItemValByKey("vehicle_invoice_tax_payment_certificate_number",itemList));
        details.setMaxPeopleNum(getItemValByKey("vehicle_invoice_limit_number",itemList));
        details.setOrigin(getItemValByKey("vehicle_invoice_car_made_place",itemList));
        details.setCommodityNumber(getItemValByKey("vehicle_invoice_commodity_inspection_id",itemList));
        details.setProducerStamp(getItemValByKey("exist_invoice_seal",itemList));
        String exist_stample = getItemValByKey("exist_stample", itemList);
        if(StringUtils.isNotBlank(exist_stample)&&exist_stample.equals("True")){
            details.setCompanySeal("1");
        }else{
            details.setCompanySeal("0");
        }
        identifyResult.setDetails(details);
    }

    /**
     * 卷票
     * @param list
     * @param identifyResult
     */
    private void createParamByVatRollInvoice(ObjectList list, IdentifyResult identifyResult) {
        VatRollInvoiceDetails details=new VatRollInvoiceDetails(); // 发票识别的具体信息
        List<Item> itemList = list.getItemList();
        details.setKind(list.getKindDescription());
        details.setCode(getItemValByKey("invoice_code",itemList));
        details.setNumber(getItemValByKey("invoice_number",itemList));
        details.setDate(getItemValByKey("date_of_invoice",itemList));
        details.setCodeConfirm(getItemValByKey("machine_code",itemList));
        details.setCheckCode(getItemValByKey("check_number",itemList));
        details.setSeller(getItemValByKey("sold_name",itemList));
        details.setSellerTaxId(getItemValByKey("sold_tax_number",itemList));
        details.setBuyer(getItemValByKey("buy_name",itemList));
        details.setBuyerTaxId(getItemValByKey("buy_tax_number",itemList));
        details.setTotal(getItemValByKey("total_money",itemList));
        details.setTotalCn(getItemValByKey("total_money_big",itemList));
        String exist_invoice_seal = getItemValByKey("exist_invoice_seal", itemList);
        if(StringUtils.isNotBlank(exist_invoice_seal)&&exist_invoice_seal.equals("True")){
            details.setCompanySeal("1");
        }else{
            details.setCompanySeal("0");
        }
        details.setTitle(getItemValByKey("invoice_head",itemList));
        details.setNumberConfirm(getItemValByKey("machine_number",itemList));
        identifyResult.setDetails(details);
        VatRollInvoiceDetails.Item item=new VatRollInvoiceDetails.Item();
        item.setName(getItemValByKey("goods_name_list",itemList));
        item.setQuantity(getItemValByKey("goods_number_list",itemList));
        item.setPrice(getItemValByKey("goods_unit_price_list",itemList));
        item.setTotal(getItemValByKey("goods_money_list",itemList));
        List<VatRollInvoiceDetails.Item> listItem=new ArrayList<>();
        listItem.add(item);
        details.setItems(listItem);
    }

    /**
     * 增值税普通发票
     * @param list
     * @param identifyResult
     */
    private void createParamByVatCommonInvoice(ObjectList list, IdentifyResult identifyResult) {
        VatCommonDetail details=new VatCommonDetail(); // 发票识别的具体信息
        List<Item> itemList = list.getItemList();
        details.setKind(list.getKindDescription());

        details.setCode(getItemValByKey("vat_invoice_daima",itemList));
        details.setNumber(getItemValByKey("vat_invoice_haoma",itemList));
        details.setCodeConfirm(getItemValByKey("vat_invoice_daima_print",itemList));
        details.setNumberConfirm(getItemValByKey("vat_invoice_daima_right_side",itemList));
        details.setDate(getItemValByKey("vat_invoice_issue_date",itemList));
        details.setTotal(getItemValByKey("vat_invoice_total_cover_tax",itemList));
        details.setTotalCn(getItemValByKey("vat_invoice_total_cover_tax_digits",itemList));
        details.setTax(getItemValByKey("vat_invoice_tax_total",itemList));
        details.setCheckCode(getItemValByKey("vat_invoice_correct_code",itemList));
        details.setMachineCode(getItemValByKey("vat_invoice_machine_no",itemList));
        details.setSeller(getItemValByKey("vat_invoice_seller_name",itemList));
        details.setSellerTaxId(getItemValByKey("vat_invoice_seller_id",itemList));
        details.setSellerAddrTel(getItemValByKey("vat_invoice_seller_addr_tell",itemList));
        details.setSellerBankAccount(getItemValByKey("vat_invoice_seller_bank_account",itemList));
        details.setBuyer(getItemValByKey("vat_invoice_payer_name",itemList));
        details.setBuyerTaxId(getItemValByKey("vat_invoice_rate_payer_id",itemList));
        details.setBuyerBankAccount(getItemValByKey("vat_invoice_payer_bank_account",itemList));
        details.setBuyerAddrTel(getItemValByKey("vat_invoice_payer_addr_tell",itemList));
        String exist_stample = getItemValByKey("exist_stample", itemList);
        if(StringUtils.isNotBlank(exist_stample)&&exist_stample.equals("True")){
            details.setCompanySeal("1");
        }else{
            details.setCompanySeal("0");
        }
        details.setFormType(getItemValByKey("vat_invoice_page_number",itemList));
        details.setFormName(getItemValByKey("vat_invoice_headline_page_number",itemList));
        details.setCiphertext(getItemValByKey("vat_invoice_cipher_field",itemList));
        details.setReceiptor(getItemValByKey("vat_invoice_payee",itemList));
        details.setReviewer(getItemValByKey("vat_invoice_review",itemList));
        details.setIssuer(getItemValByKey("vat_invoice_drawer",itemList));
        details.setServiceName(getItemValByKey("vat_invoice_type",itemList));
        details.setRemark(getItemValByKey("vat_invoice_total_note",itemList));
        details.setAgentMark(getItemValByKey("vat_invoice_dai_kai_flag",itemList));
        details.setTitle(getItemValByKey("vat_invoice_headline_page_number",itemList));
        details.setElectronicNumber(getItemValByKey("digital_elec_invoice_number",itemList));
        details.setProducerStamp(getItemValByKey("exist_manufacture_supervising_seal",itemList));
        //区块链
        InvoiceType invoiceType = InvoiceType.fromString(list.getType());
        if(invoiceType.getDescription().equals("区块链电子发票")){
            details.setBlockChain("1");
        }else if(invoiceType.getDescription().equals("增值税电子普通发票")){
            details.setTransitMark("1");
        }else if(invoiceType.getDescription().equals("增值税专用发票")||invoiceType.getDescription().equals("增值税电子专用发票")){
            details.setElectronicMark("1");
        }else{
            details.setTransitMark("0");
            details.setBlockChain("0");
            details.setElectronicMark("0");
        }
        VatCommonDetail.Item item=new VatCommonDetail.Item();
        item.setName(getItemValByKey("vat_invoice_goods_list",itemList));
        item.setSpecification(getItemValByKey("vat_invoice_plate_specific",itemList));
        item.setUnit(getItemValByKey("vat_invoice_electrans_unit",itemList));
        item.setQuantity(getItemValByKey("vat_invoice_electrans_quantity",itemList));
        item.setPrice(getItemValByKey("vat_invoice_electrans_unit_price",itemList));
        item.setTotal(getItemValByKey("vat_invoice_total",itemList));
        item.setTaxRate(getItemValByKey("vat_invoice_tax_rate",itemList));
        item.setTax(getItemValByKey("vat_invoice_tax_total",itemList));
        List<VatCommonDetail.Item> listItem=new ArrayList<>();
        listItem.add(item);
        details.setItems(listItem);

        identifyResult.setDetails(details);
    }

    private void createParamByNonTaxIncomeBill(ObjectList list, IdentifyResult identifyResult) {
        NonTaxIncomeBillDetails details=new NonTaxIncomeBillDetails(); // 发票识别的具体信息
        List<Item> itemList = list.getItemList();
        details.setKind(list.getKindDescription());
        details.setBillCode(getItemValByKey("EInvoiceCode",itemList));
        details.setBillNumber(getItemValByKey("EInvoiceNumber",itemList));
        details.setCheckCode(getItemValByKey("RandomNumber",itemList));
        details.setChecker(getItemValByKey("Checker",itemList));
        details.setDate(getItemValByKey("IssuedDate",itemList));
        details.setPayee(getItemValByKey("InvoicingPartyName",itemList));
        details.setPayer(getItemValByKey("PayerPartyName",itemList));
        details.setPaymentCode(getItemValByKey("PayerPartyCode",itemList));
        details.setReceiver(getItemValByKey("RecName",itemList));
        details.setTotal(getItemValByKey("TotalAmount",itemList));
        details.setTotalWords(getItemValByKey("TotalAmount_Words",itemList));

        identifyResult.setDetails(details);
        NonTaxIncomeBillDetails.Item item=new NonTaxIncomeBillDetails.Item();
        item.setAmount(getItemValByKey("ItemAmount",itemList));
        item.setProjectCode(getItemValByKey("ItemCode",itemList));
        item.setProjectName(getItemValByKey("ItemName",itemList));
        item.setQuantity(getItemValByKey("ItemQuantity",itemList));
        item.setStandardOfCharge(getItemValByKey("ItemStd",itemList));
        item.setUom(getItemValByKey("ItemUnit",itemList));

        List<NonTaxIncomeBillDetails.Item> listItem=new ArrayList<>();
        listItem.add(item);
        details.setItems(listItem);
    }

    /**
     * 医疗票据
     * @param list
     * @param identifyResult
     */
    private void createParamByMedical(ObjectList list, IdentifyResult identifyResult) {
        MedicalDetails details=new MedicalDetails(); // 发票识别的具体信息
        List<Item> itemList = list.getItemList();
        details.setKind(list.getKindDescription());
        details.setBillCode(getItemValByKey("invoice_bar_code",itemList));
        details.setBillNumber(getItemValByKey("invoice_number",itemList));
        details.setGender(getItemValByKey("sex",itemList));
        details.setMedicalInstitutionType(getItemValByKey("medical_institution_type",itemList));
        details.setMedicalInsuranceType(getItemValByKey("medical_insurance_type",itemList));
        details.setPayer(getItemValByKey("name",itemList));
        details.setSocialCreditCode(getItemValByKey("social_security_number",itemList));
        details.setTotal(getItemValByKey("amount_small",itemList));
        details.setTotalWords(getItemValByKey("amount_big",itemList));
        identifyResult.setDetails(details);
        MedicalDetails.Item item=new MedicalDetails.Item();
        List<MedicalDetails.Item> listItem=new ArrayList<>();
        listItem.add(item);
        details.setItems(listItem);
    }

    /**
     * 机打发票
     * @param list
     * @param identifyResult
     */
    private void createParamByGeneral(ObjectList list, IdentifyResult identifyResult) {
        GeneralDetails details=new GeneralDetails(); // 发票识别的具体信息
        List<Item> itemList = list.getItemList();
        String exist_invoice_seal = getItemValByKey("exist_invoice_seal", itemList);
        if(StringUtils.isNotBlank(exist_invoice_seal)&&exist_invoice_seal.equals("True")){
            details.setCompanySeal("1");
        }else{
            details.setCompanySeal("0");
        }
        details.setKind(list.getKindDescription());
        details.setCode(getItemValByKey("invoice_code",itemList));
        details.setNumber(getItemValByKey("invoice_number",itemList));
        details.setDate(getItemValByKey("date",itemList));
        details.setTime(getItemValByKey("time",itemList));
        details.setTotal(getItemValByKey("money",itemList));
        details.setSeller(getItemValByKey("seller",itemList));
        details.setSellerTaxId(getItemValByKey("seller_tax_id",itemList));
        details.setBuyer(getItemValByKey("buyer",itemList));
        details.setBuyerTaxId(getItemValByKey("buyer_tax_id",itemList));
        identifyResult.setDetails(details);
        GeneralDetails.Item item=new GeneralDetails.Item();
        List<GeneralDetails.Item> listItem=new ArrayList<>();
        listItem.add(item);
        details.setItems(listItem);

    }

    /**
     * 消费小票
     * @param list
     * @param identifyResult
     */
    private void createParamByShop(ObjectList list, IdentifyResult identifyResult) {
        ShopDetails details=new ShopDetails(); // 发票识别的具体信息
        List<Item> itemList = list.getItemList();
        details.setStoreName(getItemValByKey("shop",itemList));
        details.setDate(getItemValByKey("date",itemList));
        details.setTotal(getItemValByKey("money",itemList));
        identifyResult.setDetails(details);
    }

    /**
     * 航空运输电子客票行程单
     * @param list
     * @param identifyResult
     */
    private void createParamByAir(ObjectList list, IdentifyResult identifyResult) {
        AirDetails details=new AirDetails(); // 发票识别的具体信息
        List<Item> itemList = list.getItemList();
        details.setUserName(getItemValByKey("passenger_name",itemList));
        details.setUserId(getItemValByKey("id_no",itemList));
        details.setNumber(getItemValByKey("e_ticket_no",itemList));
        details.setDate(getCnDateTime(getItemValByKey("issued_date",itemList)));
        details.setAgentcode(getItemValByKey("agentcode",itemList));
        details.setIssueBy(getItemValByKey("issued_by",itemList));
        details.setFare(getItemValByKey("fare",itemList));
        details.setTax(getItemValByKey("other_taxes",itemList));
        details.setFuelSurcharge(getItemValByKey("fuel_surcharge",itemList));
        details.setCaacDevelopmentFund(getItemValByKey("civil_aviation_fund",itemList));
        details.setInsurance(getItemValByKey("insurance",itemList));
        details.setTotal(getItemValByKey("total",itemList));
        details.setEndorsement(getItemValByKey("restriction",itemList));
        List<List<Item>> flightDataList = list.getFlightDataList();
        if(CollectionUtil.isNotEmpty(flightDataList)){
            List<AirDetails.FlightInfo> flights=new ArrayList<>(); // 航班信息
            flightDataList.forEach(item->{
                AirDetails.FlightInfo flightInfo=new AirDetails.FlightInfo();
                flightInfo.setFrom(getItemValByKey("from",item));
                flightInfo.setTo(getItemValByKey("to",item));
                flightInfo.setFlightNumber(getItemValByKey("flight_number",item));
                flightInfo.setDate(getItemValByKey("date",item));
                flightInfo.setTime(getItemValByKey("time",item));
                flightInfo.setSeat(getItemValByKey("seat_class",item));
                flightInfo.setAllow(getItemValByKey("allow",item));
                flightInfo.setFareBasis(getItemValByKey("fare_basis",item));
                flights.add(flightInfo);
            });
            details.setFlights(flights);
        }
        details.setKind(list.getKindDescription());
        identifyResult.setDetails(details);
    }

    /**
     * 客运汽车
     * @param list
     * @param identifyResult
     */
    private void createParamByPassengerTranSport(ObjectList list, IdentifyResult identifyResult) {
        PassengerTranSportDetails details=new PassengerTranSportDetails(); // 发票识别的具体信息
        List<Item> itemList = list.getItemList();
        details.setCode(getItemValByKey("invoice_code",itemList));
        details.setNumber(getItemValByKey("invoice_number",itemList));
        details.setDate(getItemValByKey("date",itemList));
        details.setTime(getItemValByKey("time",itemList));
        details.setTotal(getItemValByKey("money",itemList));
        details.setName(getItemValByKey("passenger_name",itemList));
        details.setUserId(getItemValByKey("passenger_id",itemList));
        String exist_invoice_seal = getItemValByKey("exist_invoice_seal", itemList);
        if(StringUtils.isNotBlank(exist_invoice_seal)&&exist_invoice_seal.equals("True")){
            details.setCompanySeal("1");
        }else{
            details.setCompanySeal("0");
        }
        details.setKind(list.getKindDescription());
        identifyResult.setDetails(details);
    }

    /**
     * 过路费发票
     * @param list
     * @param identifyResult
     */
    private void createParamByVehicle(ObjectList list, IdentifyResult identifyResult) {
        VehicleDetails details=new VehicleDetails(); // 发票识别的具体信息
        List<Item> itemList = list.getItemList();
        details.setCode(getItemValByKey("toll_code",itemList));
        details.setNumber(getItemValByKey("toll_number",itemList));
        details.setDate(getItemValByKey("date",itemList));
        details.setTime(getItemValByKey("time",itemList));
        details.setTotal(getItemValByKey("money",itemList));
        details.setKind(list.getKindDescription());
        identifyResult.setDetails(details);
    }

    /**
     * 定额发票
     * @param list
     * @param identifyResult
     */
    private void createParamByQuota(ObjectList list, IdentifyResult identifyResult) {
        QuotaDetails details=new QuotaDetails(); // 发票识别的具体信息
        List<Item> itemList = list.getItemList();
        details.setCode(getItemValByKey("quota_invoice_code",itemList));
        details.setNumber(getItemValByKey("quota_invoice_number",itemList));
        details.setTotal(getItemValByKey("money_small",itemList));
        details.setKind(list.getKindDescription());
        details.setTotalCn(getItemValByKey("money_big",itemList));
        String exist_invoice_seal = getItemValByKey("exist_invoice_seal", itemList);
        if(StringUtils.isNotBlank(exist_invoice_seal)&&exist_invoice_seal.equals("True")){
            details.setCompanySeal("1");
        }else{
            details.setCompanySeal("0");
        }
        identifyResult.setDetails(details);
    }

    /**
     * 火车票
     * @param list
     * @param identifyResult
     */
    private void createParamByTrain(ObjectList list, IdentifyResult identifyResult) {
        TrainDetails details=new TrainDetails(); // 发票识别的具体信息
        List<Item> itemList = list.getItemList();
        details.setNumber(getItemValByKey("ticket_number",itemList));
        details.setDate(getDate(getItemValByKey("departure_date",itemList)));
        details.setTime(getTime(getItemValByKey("departure_date",itemList)));
        details.setName(getItemValByKey("passenger_name",itemList));
        details.setUserId(getItemValByKey("passenger_id",itemList));
        details.setStationGeton(getItemValByKey("departure_station",itemList));
        details.setStationGetoff(getItemValByKey("arrival_station",itemList));
        details.setTrainNumber(getItemValByKey("train_number",itemList));
        details.setSeat(getItemValByKey("class",itemList));
        details.setTotal(getItemValByKey("price",itemList));
        details.setGateNumber(getItemValByKey("check",itemList));
        details.setSeatNumber(getItemValByKey("seat_number",itemList));
        details.setKind(list.getKindDescription());
        identifyResult.setDetails(details);
    }

    /**
     * 获取图片分辨率
     * @param imageData
     * @return
     */
    public static List<Integer> getImageSize(byte[] imageData) {
        List<Integer> imageSize = new ArrayList<>();
        try {
            ByteArrayInputStream inputStream = new ByteArrayInputStream(imageData);
            BufferedImage image = ImageIO.read(inputStream);

            if (image != null) {
                imageSize.add(image.getWidth());
                imageSize.add(image.getHeight());
            }
        } catch (IOException e) {
            log.error("获取图片分辨率异常",e);
            // 如果发生异常，返回空的列表
            return null; // 这里也可以选择打印异常信息
        }
        return imageSize;
    }

    /**
     * 出租车票据数据组装
     * @param list
     * @param taxiParam
     */
    private void createParamByTaxi(ObjectList list, IdentifyResult taxiParam) {
        TaixDetails details=new TaixDetails(); // 发票识别的具体信息
        List<Item> itemList = list.getItemList();
        details.setCode(getItemValByKey("invoice_code",itemList));
        details.setNumber(getItemValByKey("invoice_no",itemList));
        details.setDate(getItemValByKey("date",itemList));
        details.setTime_geton(getItemValByKey("boarding_time",itemList));
        details.setTime_getoff(getItemValByKey("landing_time",itemList));
        details.setMileage(getItemValByKey("mileage",itemList));
        details.setTotal(getItemValByKey("sum",itemList));
        details.setPlace(getItemValByKey("location",itemList));
        details.setKind(list.getKindDescription());
        details.setLicense_plate(getItemValByKey("taxi_no",itemList));
        details.setSurcharge(getItemValByKey("oil",itemList));
        details.setFare(getItemValByKey("price",itemList));
        taxiParam.setDetails(details);
    }

    /**
     * 读取对象list快捷方法
     * @param key
     * @param itemList
     * @return
     */
    String getItemValByKey(String key,List<Item> itemList){
        Optional<Item> optionalItem = itemList.stream().filter(e -> e.getKey().equals(key)).findFirst();
        if(optionalItem.isPresent()){
            return optionalItem.get().getValue();
        }
        return null;
    }

    /**
     * 构建请求文件
     * @param request
     * @return
     * @throws IOException
     */
    public byte[] processImageUploadRequest(ImageUploadRequest request) throws IOException {
        if (request.getImage_file() != null && !request.getImage_file().isEmpty()) {
            // 处理图片文件
            return request.getImage_file().getBytes();
        } else if (request.getImage_url() != null && !request.getImage_url().isEmpty()) {
            // 从URL下载图片并转换为二进制流
            byte[] imageBytes = restTemplate.getForObject(request.getImage_url(), byte[].class);
            if (imageBytes == null) {
                throw new IOException("Failed to download image from URL");
            }
            return imageBytes;
        } else if (request.getImage_data() != null && !request.getImage_data().isEmpty()) {
            // 处理Base64编码的图片数据
            // 使用Java 8的Base64类进行解码
            return Base64.getDecoder().decode(request.getImage_data());
        } else {
            throw new IllegalArgumentException("No valid image data provided");
        }
    }

}
